package gitee.blacol.myIdUtil.entity;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import gitee.blacol.myIdUtil.entity.util.ValueUtil;
import gitee.blacol.myIdUtil.enums.PropType;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;

@Data
@NoArgsConstructor
public class ObjectId<E> extends IdThing{
    private E obj;
    private LinkedHashMap<String, PropType> propMap;
    private String strPrefix="";
    private String strSuffix="";
    private String integerFormat="";
    private String doubleFormat="";
    private String dateFormat="";
    private boolean useSeparator=false;
    private boolean isPrefixNull(){
        return strPrefix==null||strPrefix.equals("");
    }
    private boolean isSuffixNull(){
        return strSuffix==null||strSuffix.equals("");
    }

    @Override
    public String generic() throws IOException {
        File file=new File(filePath);
        if (!file.exists()){
            file.createNewFile();
        }
        //ID拼接
        StringBuilder stringBuilder=new StringBuilder();
        Set<String> keySet = propMap.keySet();
        Iterator<String> iterator=keySet.iterator();
        while (iterator.hasNext()){
            String key = iterator.next();
            PropType propType = propMap.get(key);
            try {
                switch (propType){
                    case INTEGER-> {
                        Integer integer= (Integer) ValueUtil.getValue(obj,key,propType);
                        stringBuilder.append(String.format(integerFormat, integer));
                    }
                    case DOUBLE->
                    {
                        Double integer= (Double) ValueUtil.getValue(obj,key,propType);
                        stringBuilder.append(String.format(doubleFormat, integer));
                    }
                    case STRING->
                    {
                        if (!isPrefixNull())
                            stringBuilder.append(strPrefix);
                        String integer= (String) ValueUtil.getValue(obj,key,propType);
                        stringBuilder.append(integer);
                        if (!isSuffixNull())
                            stringBuilder.append(strSuffix);
                    }
                    case DATE->{
                        Date integer= (Date) ValueUtil.getValue(obj,key,propType);
                        SimpleDateFormat simpleDateFormat=new SimpleDateFormat(dateFormat);
                        String formated = simpleDateFormat.format(integer);
                        stringBuilder.append(formated);
                    }
                }
            } catch (NoSuchFieldException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        stringBuilder.append(String.format(indexFormat,index));
        index+=1;
        SerializeConfig config=new SerializeConfig(true);
        String jsonString = JSON.toJSONString(this,config,SerializerFeature.MapSortField);
        OutputStream os=new FileOutputStream(file);
        os.write(jsonString.getBytes(StandardCharsets.UTF_8));
        os.close();
        return stringBuilder.toString();
    }

    @Override
    public Boolean continueIndex() throws IOException {
        if (!filePath.equals("")){
            File f=new File(filePath);
            if (f.exists()){
                InputStream is=new FileInputStream(f);
                byte[] b=new byte[is.available()];
                is.read(b);
                String jsonString=new String(b,StandardCharsets.UTF_8);
                ObjectId<E> complexId = JSON.toJavaObject(JSON.parseObject(jsonString,Feature.OrderedField), ObjectId.class);
                this.index=complexId.getIndex();
                this.filePath=complexId.getFilePath();
                this.indexFormat=complexId.getIndexFormat();
                this.separator=complexId.getSeparator();
                this.useSeparator=complexId.isUseSeparator();
                this.strPrefix=complexId.getStrPrefix();
                this.strSuffix=complexId.getStrSuffix();
                this.doubleFormat=complexId.getDoubleFormat();
                this.integerFormat=complexId.getIntegerFormat();
                this.dateFormat=complexId.getDateFormat();
                this.propMap=complexId.getPropMap();
                is.close();
                return true;
            }else{
                System.out.println("文件："+filePath+"不存在！");
                return false;
            }
        }else{
            System.out.println("没有设置文件路径，因此无法恢复");
            return false;
        }
    }
}
